xquery version "3.0";

module namespace api = "api";

import module namespace goods="shop/goods" at "goods/crud.xqm";
import module namespace secure="secure" at "security.xqm";

declare %private function local:call($name) {
    for $m in ("shop/goods", "secure") 
    for $f in util:list-functions($m)
    let $i := util:inspect-function($f)
    return 
        if ($i/annotation[@namespace eq "api"][QName(@name, "api") eq QName("api:" || $name, "api")])
            then
                $f
            else
                ()
        
};   

declare function api:request($req){
    api:request(
        $req,
        element {$req} {
            for $i in request:get-parameter-names()
            let $v := request:get-parameter($i, "")
            return 
                element {$i} {
                    try {
                        util:parse($v)    
                    } catch * {$v}
                }
        }
    )
};

declare function api:request($req, $data) {
    let $actions := local:call($req)
    return
        if (exists($actions))
            then
                for $i in $actions
                return
                    try {
                        $i($data)
                    } catch * {
                        api:exception($req, $err:code , $err:description, $err:value)
                    }
            else
                api:exception($req, "err:XPDY0002", "Handler not defined", $req)
};

declare function api:exception($req, $code , $description, $value) {
    element exception {
        element request {$req},
        element code {$code},
        element description {$description},
        element value {$value}
    }
};
